package PushSDK

import (
	"fmt"
	"net/http"
)

var (
	protocal      		string = "http://"
	domain        		string = "api.tuisong.baidu.com/rest/3.0"
	class         		string = "/push"
	class_app		string = "/app"
	class_tag		string = "/tag"
	httpMethod    		string = "POST"
	single_method 		string = "/single_device"
	all_method		string = "/all"
	tag_method		string = "/tags"
	create_tag_method 	string = "/create_tag"
	del_tag_method 		string = "/del_tag"
	add_dev_to_tag_method 	string = "/add_devices"
	del_dev_from_tag_method	string = "/del_devices"
)

func (bp *BaiduPush) Init(ak string, sk string) {
	bp.Query = protocal + domain
	bp.Client = &http.Client{}
	bp.Ak = ak
	bp.Sk = sk
	return
}

func (bp *BaiduPush) SetApiKey(Ak string) {
	bp.Ak = Ak
}

func (bp *BaiduPush) SetSecretKey(Sk string) {
	bp.Sk = Sk
}

func (bp *BaiduPush) SetClientType(ctype int) {
	bp.ClientType = ctype
}

func (bp *BaiduPush) GetRequestId() int {
	return bp.RequestId
}

func (bp *BaiduPush) GetLastError() error {
	return bp.Err
}

/*
	Push, the core method of BaiduPush. It send and parse the requrest, receive
	response from the server. opt is the request param struct, if param is not
	REQUIRED, we can leave it to 0(int) or ""(string)
*/
func (bp *BaiduPush) Push(method string, opt interface{}, respData interface{}) (err error) {
	var (
		req  *http.Request
		resp *http.Response
	)

	c := bp.Client
	addr := bp.Query + method
	fmt.Println(addr)
	req, err = getBaiduReq(httpMethod, addr, bp.Ak, bp.Sk, opt)
	if err != nil {
		fmt.Println("getBaiduReq error:", err)
		return
	}

	resp, bp.Err = c.Do(req)
	if bp.Err != nil {
		fmt.Println(addr, bp.GetLastError())
		return
	}
	defer resp.Body.Close()

	if bp.Err = getRespData(resp, respData); bp.GetLastError() != nil {
		fmt.Println(bp.GetLastError())
		return
	}

	return
}

func (bp *BaiduPush) PushMsgToSingleDevice(opt *PushSingleDevOpt) (msgId string, sendTime int64, err error) {
	var (
		resp PushSingleDevResp
	)

	if err = bp.Push(class + single_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	msgId = resp.ResponseData.MsgId
	sendTime = resp.ResponseData.SendTime

	return
}

func (bp *BaiduPush) PushMsgToAll(opt *PushAllOpt)(msgId string, sendTime int64,timerId string, err error){
	var (
		resp PushAllResp
	)

	if err = bp.Push(class + all_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	msgId = resp.ResponseData.MsgId
	sendTime = resp.ResponseData.SendTime
	timerId = resp.ResponseData.TimerId
	return
}

func (bp *BaiduPush) PushMsgToTag(opt *PushTagOpt)(msgId string, sendTime int64,timerId string, err error) {
	var (
		resp PushTagResp
	)

	if err = bp.Push(class + tag_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	msgId = resp.ResponseData.MsgId
	sendTime = resp.ResponseData.SendTime
	timerId = resp.ResponseData.TimerId
	return
}

func (bp *BaiduPush) CreateTag(opt *CreateTagOpt)(tag string, result int, err error) {
	var (
		resp CreateTagResp
	)

	if err = bp.Push(class_app + create_tag_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	tag = resp.ResponseData.Tag
	result = resp.ResponseData.Result
	return
}

func (bp *BaiduPush) DeleteTag(opt *DelTagOpt)(tag string, result int, err error) {
	var (
		resp DelTagResp
	)

	if err = bp.Push(class_app + del_tag_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	tag = resp.ResponseData.Tag
	result = resp.ResponseData.Result
	return
}

func (bp *BaiduPush) AddChannelToTag(opt *AddDevToTagOpt)(result []int, err error) {
	var (
		resp AddDevToTagResp
	)

	if err = bp.Push(class_tag + add_dev_to_tag_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	result = resp.ResponseData.Result
	return
}

func (bp *BaiduPush) DeleteChannelFromTag(opt *DelDevFromTagOpt)(result []int, err error) {
	var (
		resp DelDevFromTagResp
	)

	if err = bp.Push(class_tag + del_dev_from_tag_method, opt, &resp); err != nil {
		fmt.Println("BaiduPush error:", err)
		return
	}

	if resp.ErrCode != 0 {
		fmt.Println(resp.ErrCode, resp.ErrMsg)
		return
	}

	bp.RequestId = resp.RequestId
	result = resp.ResponseData.Result
	return
}
